package com.ltv.xiangqibook;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.ltv.xiangqibook.common.GameIDCreator;
import com.ltv.xiangqibook.common.XmlUtil;
import com.ltv.xiangqibook.model.Game;
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

public class GameGenerator {

	public static void main(String[] args) {
		try {
			createXML(new File(args[0]));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void createXML(File path) throws Exception {

		// initiating document factory
		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder documentBuilder = documentBuilderFactory
				.newDocumentBuilder();
		Document document = documentBuilder.newDocument();
		Element rootElement = document.createElement("games");
		document.appendChild(rootElement);

		// First call to explore the path
		listDirectories(rootElement, document, path, path.getAbsolutePath());

		//print
		OutputFormat format = new OutputFormat(document);
		format.setIndenting(true);
		format.setLineWidth(Integer.MAX_VALUE);

		//to generate output to console use this serializer
		//XMLSerializer serializer = new XMLSerializer(System.out, format);

		//to generate a file output use fileoutputstream instead of system.out
		XMLSerializer serializer = new XMLSerializer(
				new FileOutputStream(new File("games.xml")), format);

		serializer.serialize(document);
	}

	public static void listDirectories(Element rootElement, Document document, File file, String bookLocation) throws Exception {

		if (file.getName().indexOf(".svn") == -1) {
			File[] children = file.listFiles();

			if (children != null) {
				Arrays.sort(children);
				for (File child : children) {
					if (child.getName().indexOf(".svn") == -1 && child.isFile()) {
						if (child.getName().endsWith(".html")) {
							Game game = new Game();
							game.setLocation(GameIDCreator.getGameLocation(child, bookLocation));
							game.setId(GameIDCreator.getGameID(child, bookLocation));
							game.setComment("");
							
							Element childElement = document.createElement("game");

							Element commentElm = document.createElement("comment");

							String originComment = game.getComment();
							String strippedComment = XmlUtil.stripNonValidXMLCharacters(originComment);
							commentElm.setTextContent(strippedComment);

							if (!originComment.equals(strippedComment)) {
								System.out.println("Invalid Xml characters in: " + child.getAbsolutePath());
							}

							Element locationElm = document.createElement("location");
							locationElm.setTextContent(game.getLocation());

							Element idElm = document.createElement("id");
							idElm.setTextContent(game.getId());

							childElement.appendChild(idElm);
							childElement.appendChild(locationElm);
							childElement.appendChild(commentElm);


							rootElement.appendChild(childElement);
							
							FileOutputStream fo = new FileOutputStream("views/" + game.getId() + ".html");
							fo.write(getBytesFromInputStream(new FileInputStream(child)));
							fo.close();
						}
					}
					listDirectories(rootElement, document, child, bookLocation);
				}
			}
		}
	}

	private static byte[] getBytesFromInputStream(InputStream is) throws IOException {
		ByteArrayOutputStream buffer = new ByteArrayOutputStream();

		int nRead;
		byte[] data = new byte[1024];

		while ((nRead = is.read(data, 0, data.length)) != -1) {
		  buffer.write(data, 0, nRead);
		}

		buffer.flush();

		return buffer.toByteArray();
	}

}
